<template>
  <div>
    <base-table ref="table" :search-params="searchParams" :columns="columnsAction" :async-fc="page">
      <template #tableHeader>
        <t-button theme="primary" @click="insert">{{ t('components.commonTable.insert') }}</t-button>
        <t-button theme="warning" @click="batchDelete">{{ t('components.commonTable.batchDelete') }}</t-button>
      </template>
    </base-table>
    <t-dialog v-model:visible="modalOpen" @confirm="onModalSubmit">
      <t-form ref="submitFormRef" :rules="rules" :data="submitForm">
        <t-form-item :label="t('pages.userRole.name')" name="name">
          <t-input v-model="submitForm.name" :placeholder="t('pages.userRole.namePlaceholder')" />
        </t-form-item>
        <t-form-item :label="t('pages.userRole.code')" name="code">
          <t-input v-model="submitForm.code" :placeholder="t('pages.userRole.codePlaceholder')" />
        </t-form-item>
        <t-form-item :label="t('pages.userRole.status')" name="status">
          <t-select v-model="submitForm.status" :placeholder="t('pages.userRole.statusPlaceholder')">
            <t-option :value="0" label="正常" />
            <t-option :value="1" label="禁用" />
          </t-select>
        </t-form-item>
        <t-form-item :label="t('pages.userRole.remark')" name="remark">
          <t-input v-model="submitForm.remark" :placeholder="t('pages.userRole.remarkPlaceholder')" />
        </t-form-item>
      </t-form>
    </t-dialog>
    <t-drawer v-model:visible="rolePerVisible" size="medium" header="角色权限分配">
      <t-tree
        :data="treeData"
        checkable
        :value="perData"
        check-strictly
        icon
        line
        expand-parent
        expand-all
        lazy
        value-mode="all"
        @change="onTreeChange"
      >
        <template #line="{ node }">
          <t-icon v-if="node.data?.icon" :name="node.data?.icon"></t-icon>
          <t-icon v-else name="map-3d"></t-icon>
        </template>
      </t-tree>
    </t-drawer>
  </div>
</template>
<script setup lang="ts">
import {
  DialogPlugin,
  FormInstanceFunctions,
  Link,
  MessagePlugin,
  Space,
  TreeNodeValue,
  TreeProps,
} from 'tdesign-vue-next';
import { computed, onMounted, ref } from 'vue';

import { assignPermission, getPermissionByRoleId, tree } from '@/api/sys_permission';
import { batchDeleteById, deleteById, insertApi, page, updateApi } from '@/api/sys_role';
import baseTable from '@/components/base-table/index.vue';
import { t } from '@/locales';

import { getColumns, getRules, getSearchParams } from './constants';

const submitForm = ref<any>({});
const modalOpen = ref(false);
const submitFormRef = ref<FormInstanceFunctions>(null);
const table = ref<_TableInstanceFunctions>(null);
const rolePerVisible = ref(false);
const treeData = ref<TreeProps['data']>([]);
const perData = ref<TreeNodeValue[]>([]);
const roleId = ref<number>(null);
const searchParams = computed(() => getSearchParams());
const rules = computed(() => getRules());
const columns = computed(() => getColumns());

const columnsAction = computed(() =>
  columns.value.concat([
    {
      align: 'center',
      fixed: 'right',
      colKey: 'op',
      title: t('components.commonTable.operation'),
      cell: (h, { row }) =>
        h(
          Space,
          {
            split: 'line',
          },
          () => [
            h(
              Link,
              {
                theme: 'primary',
                underline: false,
                onClick: () => {
                  submitForm.value = row;
                  modalOpen.value = true;
                },
              },
              () => t('components.commonTable.edit'),
            ),
            h(
              Link,
              {
                theme: 'success',
                underline: false,
                onClick: async () => {
                  roleId.value = row.id;
                  const data = await getPermissionByRoleId(row.id);
                  perData.value = data;
                  rolePerVisible.value = true;
                },
              },
              () => t('components.commonTable.allocation'),
            ),
            h(
              Link,
              {
                theme: 'danger',
                underline: false,
                onClick: () => {
                  const confirmDialog = DialogPlugin.confirm({
                    header: t('components.commonTable.tips'),
                    body: t('components.commonTable.deleteConfirm'),
                    confirmBtn: {
                      content: t('components.commonTable.submit'),
                      theme: 'primary',
                      loading: false,
                    },
                    cancelBtn: {
                      content: t('components.commonTable.cancel'),
                      theme: 'default',
                      loading: false,
                    },
                    theme: 'warning',
                    onConfirm: async () => {
                      confirmDialog.update({
                        confirmBtn: { content: t('components.commonTable.submitting'), loading: true },
                      });
                      await deleteById(row.id);
                      MessagePlugin.success(t('components.commonTable.deleteSuccess'));
                      table.value.onSearch();
                      confirmDialog.update({
                        confirmBtn: { content: t('components.commonTable.submit'), loading: false },
                      });
                      confirmDialog.hide();
                    },
                  });
                },
              },
              () => t('components.commonTable.delete'),
            ),
          ],
        ),
    },
  ]),
);

const insert = () => {
  modalOpen.value = true;
  submitForm.value = {
    status: 0,
  };
};

/**
 * 提交表单
 */
const onModalSubmit = async () => {
  const valid = await submitFormRef.value.validate();
  if (valid && typeof valid !== 'boolean') {
    MessagePlugin.warning(Object.values(valid)[0][0].message);
    return;
  }
  if (submitForm.value.id) {
    await updateApi(submitForm.value);
    MessagePlugin.success('修改成功！');
  } else {
    await insertApi(submitForm.value);
    MessagePlugin.success('新增成功！');
  }
  modalOpen.value = false;
  table.value.onSearch();
};

/**
 * 批量删除
 */
const batchDelete = async () => {
  const selectedRows = table.value.getSelectedKeys() as number[];
  if (!selectedRows.length) {
    MessagePlugin.warning('请选择要删除的数据');
    return;
  }
  await batchDeleteById(selectedRows);
  MessagePlugin.success('批量删除成功');
  table.value.onSearch();
};

/**
 * 树形选择
 * @param value
 */
const onTreeChange = async (keys: any[], e: any) => {
  const data = await assignPermission({
    roleId: roleId.value,
    check: e.node.checked,
    permissionIds: [e.node.value],
  });
  if (data) {
    perData.value = keys;
  }
};

onMounted(async () => {
  const res = await tree();
  treeData.value = res;
});
</script>
